package com.zcb.agrimarket.utils;

import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.PutObjectRequest;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

@Slf4j
@AllArgsConstructor
@Data
public class AliyunOSSUtil {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
    private String picture;
    private String video;
    private String music;
    private String file;

    /**
     * 创建存储空间
     */
    public void insertBucket() {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 创建存储空间。
        ossClient.createBucket(MyEnvBeanUtil.getString(bucketName));
        // 关闭OSSClient。
        ossClient.shutdown();
    }


    /**
     * 上传本地文件
     * @param fileName 文件名
     * @param localFile 本地文件路径
     */
    public void uploadLocalFiles(String fileName, String localFile) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 创建PutObjectRequest对象。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, new File(String.valueOf(localFile)));
        // 上传文件。
        ossClient.putObject(putObjectRequest);
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 下载文件到本地
     * @param fileName 文件名
     * @param localFile 本地文件路径
     */
    public void download(String fileName, String localFile) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
        ossClient.getObject(new GetObjectRequest(bucketName, fileName), new File(localFile));
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 删除文件
      * @param fileName 文件名
     */
    public void deleteFile(String fileName) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 删除文件。如需删除文件夹，请将ObjectName设置为对应的文件夹名称。如果文件夹非空，则需要将文件夹下的所有object删除后才能删除该文件夹。
        ossClient.deleteObject(bucketName, fileName);
        // 关闭OSSClient。
        ossClient.shutdown();
    }


    /**
     * 上传字节数组(可用于视频、音频、图片、文件上传)
     * @param video 字节()文件
     * @param fileName 文件名
     */
    public void uploadFileByte(MultipartFile video, String fileName) {

        //转换为字节数组
        byte[] bytes = null;
        try {
            bytes = video.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 上传Byte数组。
        ossClient.putObject(bucketName, fileName, new ByteArrayInputStream(bytes));
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 视频截取帧
     * @param fileName 文件名
     * @return 图片字节流
     */
    public URL videoInterceptCover(String fileName) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 设置视频截帧操作。
        String style = "video/snapshot,t_1000,f_jpg,w_800,h_600";
        // 指定过期时间为10分钟。
        Date expiration = new Date(new Date().getTime() + 1000 * 60 * 10);
        GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, fileName, HttpMethod.GET);
        req.setExpiration(expiration);
        req.setProcess(style);
        URL signedUrl = ossClient.generatePresignedUrl(req);
        // 关闭OSSClient。
        ossClient.shutdown();
        return signedUrl;
    }

    /**
     * 上传网络流至阿里云
     * @param netPath 网络路径
     * @param fileName 指定文件名
     * @throws IOException
     */
    public void uploadNetFile(String netPath, String fileName) throws IOException {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        // 上传网络流。
        InputStream inputStream = new URL(netPath).openStream();
        ossClient.putObject(bucketName, fileName, inputStream);
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 自己写的
     * 上传字节数组到指定位置(可用于视频、音频、图片、文件上传)
     * @param file 文件
     */
    public String upload(MultipartFile file, String path) {
        //获取文件名
        String primitiveName = file.getOriginalFilename();
        log.info("原始文件名：{}",primitiveName);
        //拼接处理后的文件名
        String fileName = path + "/" + new Date().getTime() + "-" + primitiveName;
        log.info("拼接处理后的文件名：{}",fileName);

        //转换为字节数组
        byte[] bytes = null;
        try {
            bytes = file.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 上传Byte数组。
        //核心上传代码
        ossClient.putObject(bucketName, fileName, new ByteArrayInputStream(bytes));
        String fileUrl = "https://"+bucketName+"."+endpoint +"/"+ fileName;
        // 关闭OSSClient。
        ossClient.shutdown();
        return fileUrl;
    }
}